//package org.jeecg.common.rc.aop.dicttrans.dictaop;
//
//import cn.hutool.core.collection.CollUtil;
//import cn.hutool.core.convert.Convert;
//import cn.hutool.core.util.StrUtil;
//import com.baomidou.mybatisplus.core.metadata.IPage;
//import org.jeecg.common.core.Result;
//import org.jeecg.common.rc.aop.dicttrans.classutil.ByteBuddyUtil;
//import org.jeecg.common.rc.aop.dicttrans.dictaop.entity.TransInfo;
//import org.jeecg.common.rc.aop.dicttrans.dictaop.util.TransUtil;
//import org.jeecg.common.util.RefUtil;
//import org.jeecg.common.util.spelutil.SpELUtils;
//import org.jeecg.crud.sys.api.CommonAPI;
//import org.jeecg.crud.sys.model.DictModel;
//import com.fasterxml.jackson.databind.ObjectMapper;
//import lombok.Getter;
//import lombok.SneakyThrows;
//import lombok.extern.slf4j.Slf4j;
//import org.aspectj.lang.ProceedingJoinPoint;
//import org.aspectj.lang.annotation.Around;
//import org.aspectj.lang.annotation.Aspect;
//import org.aspectj.lang.annotation.Pointcut;
//import org.springframework.beans.factory.annotation.Autowired;
//import org.springframework.stereotype.Component;
//
//import java.util.*;
//import java.util.function.BiFunction;
//import java.util.function.Function;
//import java.util.function.Predicate;
//import java.util.stream.Collectors;
//
///**
// * dict aop4
// *
// * @author zjarlin
// * @since 2023/03/25
// */
//@Aspect
//@Component
//@Slf4j
////@SuppressWarnings("all")
//public class DictAop {
//    @Getter
//    private final Map<String, Object> spelContextMap = new HashMap<>();
//    @Autowired
//    ObjectMapper objectMapper;
//    @Autowired
//    TransUtil transUtil;
//    //批量翻译接口
////    private BiFunction<String, String, Map<String, List<DictModel>>> translateManyDictFun = commonAPI::translateManyDict;
//    @Autowired
//    private CommonAPI commonAPI;
//    @Getter
//    private NeedTransLate dictCode2Name;
//
//    public BiFunction<Object, Function<Object, ?>, ?> matchFun(Object o) {
//        BiFunction<Object, Function<Object, ?>, ?> objectFunctionBiFunction = strategy.entrySet().stream().filter(e -> {
//            Predicate<Object> key = e.getKey();
//            boolean test = key.test(o);
//            return test;
//        }).map(e -> e.getValue()).findAny().orElse(null);
//        return objectFunctionBiFunction;
//    }
//
//    /**
//     * 这里的obj指的是集合类型
//     */
//    @SneakyThrows
//    public Object transOutVOS(Object obj) {
//        if (obj instanceof String) {
//            String s = extractSingleAttributeTranslation(obj, dictCode2Name);
//            return s;
//        }
//        spelContextMap.put(TransUtil.ROOT_OBJECT, obj);
//
//        Collection<?> inVOs = (Collection<?>) obj;
//        if (CollUtil.isEmpty(inVOs)) {
//            return obj;
//        }
//        Object next = inVOs.iterator().next();
//        //利用bytebuddy递归生成嵌套代理对象
//        Object o1 = ByteBuddyUtil.genChildObjectRecursion(next, TransUtil::getNeedAddFields);
//        Class<?> afterObjectClass = o1.getClass();
//        List<?> collect = inVOs.stream().map(e -> {
//            Object convert = Convert.convert(afterObjectClass, e);
//            return convert;
//        }).collect(Collectors.toList());
//
//        //翻译过程的全部信息都在这里了 对于单个字典翻译,会按照list中所有dictCode分组TransInfo集合 会调用系统字段批量翻译
//        Map<Integer, List<TransInfo<DictCode2Name>>> collect1 = collect.stream().flatMap(item -> {
//            List<TransInfo<DictCode2Name>> process = TransUtil.process(item);
//            return process.stream();
//        }).collect(Collectors.groupingBy(TransInfo::getClassificationOfTranslation));
//        //转为临时对象List<TransInfo>后批量处理
//        /**  处理内置字典翻译*/
//        transUtil.processBuiltInDictionaryTranslation(collect1);
//        /** 处理任意表翻译 */
//        transUtil.processAnyTableTranslation(collect1);
//        /** 处理spel表达式 */
//        transUtil.processingSpelExpressions(collect1);
//
//        return collect;
//    }
//
//
//    @Pointcut("execution(* org.jeecg..BaseController.*(..))")
//    public void p1() {
//    }
//
//    @Pointcut("execution(* org.jeecg..*Controller+.*(..))")
//    public void p2() {
//    }
//
//    @Pointcut("execution(* org.jeecg..*Api+.*(..))")
//    public void p3() {
//    }
//
//    /**
//     * 该切面会对实体中属性加了注解的字段生效,支持嵌套List<T>属性 T中加了注解的也会被翻译
//     *
//     * @param pjp pjp
//     * @return {@link Object }
//     * @author zjarlin
//     * @since 2023/01/05
//     */
//    @Around("(p1()||p2()||p3()) &&  @annotation(dictCode2Name)")
//    @SneakyThrows
//    public Object transLateDict(ProceedingJoinPoint pjp, NeedTransLate dictCode2Name) {
//        Object outVO = pjp.proceed();
//        Class<?> aClass = outVO.getClass();
//        spelContextMap.put(TransUtil.OUT_VO, outVO);
//        //对于Controller直接返回String的,取NeedTransLate注解上的信息
//        if (String.class.isAssignableFrom(aClass)) {
//            spelContextMap.put(TransUtil.OUT_VO, outVO);
//            this.dictCode2Name = dictCode2Name;
//        }
//        //支持T ,Collection<T>,Ipage<T>及他们的嵌套
//        BiFunction<Object, Function<Object, ?>, ?> consumerByType = matchFun(outVO);
//        Object apply = consumerByType.apply(outVO, this::transOutVOS);
//        return apply;
//    }
//
//    private <T> String extractSingleAttributeTranslation(T fieldRuntimeValue, NeedTransLate dictCode2Name) {
//        String dictCode = dictCode2Name.dicCode();
//        String tab = dictCode2Name.tab();
//        String codeColumn = dictCode2Name.codeColumn();
//        String nameColumn = dictCode2Name.nameColumn();
//        String spelExp = dictCode2Name.spelExp();
//        if (StrUtil.isAllBlank(dictCode, tab, codeColumn, nameColumn)) {
//            return String.valueOf(fieldRuntimeValue);
//        }
//        String fieldRuntimeStrValue = String.valueOf(fieldRuntimeValue);
//        codeColumn = StrUtil.toUnderlineCase(codeColumn);
//        nameColumn = StrUtil.toUnderlineCase(nameColumn);
//        //dictCode不空 这仨参数全是空说明是内置字典翻译
//        boolean isUseSysDefaultDict = StrUtil.isNotBlank(dictCode) && StrUtil.isAllBlank(tab, codeColumn, nameColumn);
//        String string = fieldRuntimeStrValue;
//        boolean isMulti = StrUtil.contains(string, ",");
//        boolean useSpel = StrUtil.isNotBlank(spelExp);
//        String retStr = "";
//        if (!isUseSysDefaultDict && !isMulti) {
//            retStr = commonAPI.translateDictFromTable(tab, nameColumn, codeColumn, fieldRuntimeStrValue);
//        }
//        if (isUseSysDefaultDict && !isMulti) {
//            retStr = commonAPI.translateDict(dictCode, fieldRuntimeStrValue);
//        }
//        if (!isUseSysDefaultDict && isMulti) {
//            //如果是多个用逗号隔开的翻译
//            List<DictModel> dictModels = commonAPI.translateDictFromTableByKeys(tab, nameColumn, codeColumn, fieldRuntimeStrValue);
//            Map<String, String> relation = dictModels.stream().collect(Collectors.toMap(DictModel::getValue, DictModel::getLabel));
//            String[] split = fieldRuntimeStrValue.split(",");
//            retStr = Arrays.stream(split).map(relation::get).collect(Collectors.joining(","));
//        }
//        //多表翻译
//        if (isUseSysDefaultDict && isMulti) {
//            Map<String, List<DictModel>> stringListMap = commonAPI.translateManyDict(dictCode, fieldRuntimeStrValue);
//            List<DictModel> dictModels = stringListMap.get(dictCode);
//            retStr = dictModels.stream().map(DictModel::getLabel).collect(Collectors.joining(","));
//        }
//        if (useSpel) {
//            Class<?> aClass = dictCode2Name.spelValueType();
//            Map<String, Object> spelContextMap1 = this.getSpelContextMap();
//            Object spelContextMapObject = transUtil.getSpelContextMapObject();
//            Object o = SpELUtils.evaluateExpression(spelContextMapObject, spelContextMap1, spelExp, aClass);
//            retStr = o.toString();
//        }
//        return retStr;
//    }
//
//    Map<Predicate<Object>, BiFunction<Object, Function<Object, ?>, ?>> strategy = new HashMap<Predicate<Object>, BiFunction<Object, Function<Object, ?>, ?>>() {{
//        put(e -> {
//            boolean assignableFrom = Result.class.isAssignableFrom(e.getClass());
//            return assignableFrom;
//        }, (outVO, translater) -> {
//            Result result = (Result) outVO;
//            Object resultObject = result.getResult();
//            spelContextMap.put(TransUtil.OUT_VO, resultObject);
//            BiFunction<Object, Function<Object, ?>, ?> objectFunctionBiFunction = matchFun(resultObject);
//            Object apply = objectFunctionBiFunction.apply(resultObject, translater);
//            result.setResult(apply);
//            return result;
//        });
//        put(e -> IPage.class.isAssignableFrom(e.getClass()), (outVO, translater) -> {
//            spelContextMap.put(TransUtil.OUT_VO, outVO);
//            IPage ipage = (IPage) outVO;
//            List records = ipage.getRecords();
//            List apply = (List) translater.apply(records);
//            IPage iPage = ipage.setRecords(apply);
//            return iPage;
//        });
//        put(e -> List.class.isAssignableFrom(e.getClass()), (outVO, translater) -> {
//            spelContextMap.put(TransUtil.OUT_VO, outVO);
//            List records = (List) outVO;
//            List apply = (List) translater.apply(records);
//            return apply;
//        });
//        put(e -> String.class.isAssignableFrom(e.getClass()), (outVO, translater) -> {
//            spelContextMap.put(TransUtil.OUT_VO, outVO);
//            String str = (String) outVO;
//            return translater.apply(str);
//        });
//        put(obj -> RefUtil.isT(obj), (outVO, translater) -> {
//            spelContextMap.put(TransUtil.OUT_VO, outVO);
//            List<Object> list = Collections.singletonList(outVO);
//            List apply = (List) translater.apply(list);
//            return CollUtil.isEmpty(apply) ? null : apply.get(0);
//        });
//        put(RefUtil::isCollection, (outVO, translater) -> {
//            spelContextMap.put(TransUtil.OUT_VO, outVO);
//            Collection records = (Collection) outVO;
//            List apply = (List) translater.apply(records);
//            return apply;
//        });
//    }};
//
//
//}
